# -*- encoding: utf-8 -*-
"""
Copyright (c) 2023 - present SKbioinfo
"""

from apps import db
from datetime import datetime, timezone
import datetime as dt

class SampleSheet(db.Model):
    """
    SampleSheet model representing experimental sample information.
    """
    __tablename__ = 'samplesheets'
    
    id = db.Column(db.Integer, primary_key=True)
    group = db.Column(db.Integer, nullable=False, comment='Group identifier for the sample')
    host = db.Column(db.String(100), nullable=False, comment='Host organism or system')
    raw_1 = db.Column(db.String(255), nullable=True, comment='Path or identifier for raw data file 1')
    raw_2 = db.Column(db.String(255), nullable=True, comment='Path or identifier for raw data file 2 (for paired-end)')
    sample_name = db.Column(db.String(100), nullable=False, unique=True, comment='Unique name for the sample')
    split_id = db.Column(db.String(50), nullable=True, comment='Identifier for split or batch processing')
    created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = db.Column(
        db.DateTime, 
        default=lambda: datetime.now(timezone.utc),
        onupdate=lambda: datetime.now(timezone.utc)
    )

    def __repr__(self):
        return f"<SampleSheet {self.sample_name} (Group: {self.group})>"

    def to_dict(self):
        result = {}
        for c in self.__table__.columns:
            value = getattr(self, c.name)
            if isinstance(value, dt.datetime):
                value = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, dt.date):
                value = value.strftime('%Y-%m-%d')
            result[c.name] = value
        return result

class Analysis(db.Model):
    """分析任务数据模型"""
    __tablename__ = 'analysis'
    
    id = db.Column(
        db.BigInteger().with_variant(db.Integer, "sqlite"),
        primary_key=True,
        autoincrement=True,
        nullable=False,
        unique=True,
        comment='自增主键'
    )
    run_id = db.Column(
        db.String(64),
        nullable=False,
        unique=True,
        comment='分析编号'
    )
    run_name = db.Column(
        db.String(64),
        nullable=False,
        comment='分析名称'
    )
    run_description = db.Column(
        db.String(64),
        nullable=True,
        comment='分析描述'
    )
    type = db.Column(
        db.String(64),
        nullable=False,
        comment='分析类型'
    )
    run_sample_file = db.Column(
        db.String(64),
        nullable=True,
        comment='分析样本信息文件'
    )
    run_create_time = db.Column(
        db.DateTime,
        default=datetime.now(),
        nullable=True,
        comment='分析提交时间'
    )
    run_complete_time = db.Column(
        db.DateTime,
        nullable=True,
        comment='分析完成时间'
    )
    run_status = db.Column(
        db.Integer,
        nullable=True,
        comment='分析状态'
    )
    run_qc_file = db.Column(
        db.String(128),
        nullable=True,
        comment='质控结果文件'
    )
    run_result_file = db.Column(
        db.String(128),
        nullable=True,
        comment='检测结果文件'
    )
    run_trace_file = db.Column(
        db.String(128),
        nullable=True,
        comment='监控结果文件'
    )
    report_status = db.Column(
        db.Integer,
        nullable=True,
        comment='报告状态'
    )
    workflow_id = db.Column(
        db.Integer,
        nullable=True,
        comment='分析流程编号'
    )
    username = db.Column(
        db.String(64),
        nullable=True,
        comment='提交用户'
    )
  
    def to_dict(self):
        result = {}
        for c in self.__table__.columns:
            value = getattr(self, c.name)
            if isinstance(value, dt.datetime):
                value = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, dt.date):
                value = value.strftime('%Y-%m-%d')
            result[c.name] = value
        return result

class Workflow(db.Model):
    __tablename__ = 'workflows'
    workflow_id = db.Column(db.Integer, primary_key=True)
    workflow_name = db.Column(db.String(128), nullable=True)
    description = db.Column(db.String(128), nullable=True)
    version = db.Column(db.String(20), nullable=False, default='1.0')
    created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = db.Column(
        db.DateTime, 
        default=lambda: datetime.now(timezone.utc),
        onupdate=lambda: datetime.now(timezone.utc)
    )

    def to_dict(self):
        result = {}
        for c in self.__table__.columns:
            value = getattr(self, c.name)
            if isinstance(value, dt.datetime):
                value = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, dt.date):
                value = value.strftime('%Y-%m-%d')
            result[c.name] = value
        return result

class Parameter(db.Model):
    __tablename__ = 'parameters'
    param_id = db.Column(db.Integer, primary_key=True)
    param_name = db.Column(db.String(50), nullable=False, unique=True)
    display_name = db.Column(db.String(128), nullable=True)
    version = db.Column(db.String(20), nullable=False, default='1.0')
    data_type = db.Column(db.String(20), nullable=False)  # int/float/string/boolean
    unit = db.Column(db.String(20), nullable=True)
    description = db.Column(db.String(128), nullable=True)
    created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
    
    def to_dict(self):
        return {c.name: getattr(self, c.name) for c in self.__table__.columns}
    
class RunParameterValue(db.Model):
    __tablename__ = 'run_parameter_values'
    
    id = db.Column(db.Integer, primary_key=True)
    run_id = db.Column(db.String(50), db.ForeignKey('analysis.run_id'), nullable=False)
    param_id = db.Column(db.Integer, db.ForeignKey('parameters.param_id'), nullable=False)
    param_value = db.Column(db.Text, nullable=False)
    set_by = db.Column(db.String(50))
    set_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
    
    # # Relationships
    # run = db.relationship('Analysis', backref=db.backref('parameter_values', lazy=True))
    # parameter = db.relationship('Parameter', backref=db.backref('run_values', lazy=True))
    
    def to_dict(self):
        result = {}
        for c in self.__table__.columns:
            value = getattr(self, c.name)
            if isinstance(value, dt.datetime):
                value = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, dt.date):
                value = value.strftime('%Y-%m-%d')
            result[c.name] = value
        return result